package io.github.echarts.model.geometry;

import java.util.Objects;

/**
 * 表示文本的样式
 * 包括字体、大小、颜色、对齐方式等属性
 */
public class TextStyle {
    
    /**
     * 文本水平对齐方式枚举
     */
    public enum HorizontalAlign {
        /**
         * 左对齐
         */
        LEFT,
        
        /**
         * 居中对齐
         */
        CENTER,
        
        /**
         * 右对齐
         */
        RIGHT
    }
    
    /**
     * 文本垂直对齐方式枚举
     */
    public enum VerticalAlign {
        /**
         * 顶部对齐
         */
        TOP,
        
        /**
         * 居中对齐
         */
        MIDDLE,
        
        /**
         * 底部对齐
         */
        BOTTOM,
        
        /**
         * 基线对齐
         */
        BASELINE
    }
    
    /**
     * 文本装饰枚举
     */
    public enum TextDecoration {
        /**
         * 无装饰
         */
        NONE,
        
        /**
         * 下划线
         */
        UNDERLINE,
        
        /**
         * 上划线
         */
        OVERLINE,
        
        /**
         * 删除线
         */
        LINE_THROUGH
    }
    
    /**
     * 默认字体族
     */
    public static final String DEFAULT_FONT_FAMILY = "sans-serif";
    
    /**
     * 默认字体大小
     */
    public static final double DEFAULT_FONT_SIZE = 12.0;
    
    /**
     * 默认行高
     */
    public static final double DEFAULT_LINE_HEIGHT = 1.2;
    
    /**
     * 默认文本颜色
     */
    public static final Color DEFAULT_COLOR = Color.BLACK;
    
    /**
     * 默认水平对齐方式
     */
    public static final HorizontalAlign DEFAULT_HORIZONTAL_ALIGN = HorizontalAlign.LEFT;
    
    /**
     * 默认垂直对齐方式
     */
    public static final VerticalAlign DEFAULT_VERTICAL_ALIGN = VerticalAlign.BASELINE;
    
    /**
     * 字体族
     */
    private final String fontFamily;
    
    /**
     * 字体大小
     */
    private final double fontSize;
    
    /**
     * 行高
     */
    private final double lineHeight;
    
    /**
     * 文本颜色
     */
    private final Color color;
    
    /**
     * 是否粗体
     */
    private final boolean bold;
    
    /**
     * 是否斜体
     */
    private final boolean italic;
    
    /**
     * 水平对齐方式
     */
    private final HorizontalAlign horizontalAlign;
    
    /**
     * 垂直对齐方式
     */
    private final VerticalAlign verticalAlign;
    
    /**
     * 文本装饰
     */
    private final TextDecoration decoration;
    
    /**
     * 文本旋转角度（弧度）
     */
    private final double rotation;
    
    /**
     * 文本阴影偏移X
     */
    private final double shadowOffsetX;
    
    /**
     * 文本阴影偏移Y
     */
    private final double shadowOffsetY;
    
    /**
     * 文本阴影模糊半径
     */
    private final double shadowBlur;
    
    /**
     * 文本阴影颜色
     */
    private final Color shadowColor;
    
    /**
     * 创建默认文本样式
     */
    public TextStyle() {
        this(DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_COLOR);
    }
    
    /**
     * 创建文本样式，指定字体族、大小和颜色
     * 
     * @param fontFamily 字体族
     * @param fontSize 字体大小
     * @param color 文本颜色
     */
    public TextStyle(String fontFamily, double fontSize, Color color) {
        this(fontFamily, fontSize, DEFAULT_LINE_HEIGHT, color, false, false, 
             DEFAULT_HORIZONTAL_ALIGN, DEFAULT_VERTICAL_ALIGN, TextDecoration.NONE, 0, 
             0, 0, 0, null);
    }
    
    /**
     * 创建文本样式，指定字体族、大小、颜色、粗体和斜体
     * 
     * @param fontFamily 字体族
     * @param fontSize 字体大小
     * @param color 文本颜色
     * @param bold 是否粗体
     * @param italic 是否斜体
     */
    public TextStyle(String fontFamily, double fontSize, Color color, boolean bold, boolean italic) {
        this(fontFamily, fontSize, DEFAULT_LINE_HEIGHT, color, bold, italic, 
             DEFAULT_HORIZONTAL_ALIGN, DEFAULT_VERTICAL_ALIGN, TextDecoration.NONE, 0, 
             0, 0, 0, null);
    }
    
    /**
     * 创建完整的文本样式
     * 
     * @param fontFamily 字体族
     * @param fontSize 字体大小
     * @param lineHeight 行高
     * @param color 文本颜色
     * @param bold 是否粗体
     * @param italic 是否斜体
     * @param horizontalAlign 水平对齐方式
     * @param verticalAlign 垂直对齐方式
     * @param decoration 文本装饰
     * @param rotation 旋转角度（弧度）
     * @param shadowOffsetX 阴影偏移X
     * @param shadowOffsetY 阴影偏移Y
     * @param shadowBlur 阴影模糊半径
     * @param shadowColor 阴影颜色
     */
    public TextStyle(String fontFamily, double fontSize, double lineHeight, Color color, 
                    boolean bold, boolean italic, HorizontalAlign horizontalAlign, 
                    VerticalAlign verticalAlign, TextDecoration decoration, double rotation,
                    double shadowOffsetX, double shadowOffsetY, double shadowBlur, Color shadowColor) {
        this.fontFamily = fontFamily != null ? fontFamily : DEFAULT_FONT_FAMILY;
        this.fontSize = fontSize > 0 ? fontSize : DEFAULT_FONT_SIZE;
        this.lineHeight = lineHeight > 0 ? lineHeight : DEFAULT_LINE_HEIGHT;
        this.color = color != null ? color : DEFAULT_COLOR;
        this.bold = bold;
        this.italic = italic;
        this.horizontalAlign = horizontalAlign != null ? horizontalAlign : DEFAULT_HORIZONTAL_ALIGN;
        this.verticalAlign = verticalAlign != null ? verticalAlign : DEFAULT_VERTICAL_ALIGN;
        this.decoration = decoration != null ? decoration : TextDecoration.NONE;
        this.rotation = rotation;
        this.shadowOffsetX = shadowOffsetX;
        this.shadowOffsetY = shadowOffsetY;
        this.shadowBlur = shadowBlur > 0 ? shadowBlur : 0;
        this.shadowColor = shadowColor; // 可以为null，表示没有阴影
    }
    
    /**
     * 获取字体族
     * 
     * @return 字体族
     */
    public String getFontFamily() {
        return fontFamily;
    }
    
    /**
     * 获取字体大小
     * 
     * @return 字体大小
     */
    public double getFontSize() {
        return fontSize;
    }
    
    /**
     * 获取行高
     * 
     * @return 行高
     */
    public double getLineHeight() {
        return lineHeight;
    }
    
    /**
     * 获取文本颜色
     * 
     * @return 文本颜色
     */
    public Color getColor() {
        return color;
    }
    
    /**
     * 判断是否粗体
     * 
     * @return 是否粗体
     */
    public boolean isBold() {
        return bold;
    }
    
    /**
     * 判断是否斜体
     * 
     * @return 是否斜体
     */
    public boolean isItalic() {
        return italic;
    }
    
    /**
     * 获取水平对齐方式
     * 
     * @return 水平对齐方式
     */
    public HorizontalAlign getHorizontalAlign() {
        return horizontalAlign;
    }
    
    /**
     * 获取垂直对齐方式
     * 
     * @return 垂直对齐方式
     */
    public VerticalAlign getVerticalAlign() {
        return verticalAlign;
    }
    
    /**
     * 获取文本装饰
     * 
     * @return 文本装饰
     */
    public TextDecoration getDecoration() {
        return decoration;
    }
    
    /**
     * 获取旋转角度
     * 
     * @return 旋转角度（弧度）
     */
    public double getRotation() {
        return rotation;
    }
    
    /**
     * 获取阴影X偏移
     * 
     * @return 阴影X偏移
     */
    public double getShadowOffsetX() {
        return shadowOffsetX;
    }
    
    /**
     * 获取阴影Y偏移
     * 
     * @return 阴影Y偏移
     */
    public double getShadowOffsetY() {
        return shadowOffsetY;
    }
    
    /**
     * 获取阴影模糊半径
     * 
     * @return 阴影模糊半径
     */
    public double getShadowBlur() {
        return shadowBlur;
    }
    
    /**
     * 获取阴影颜色
     * 
     * @return 阴影颜色，如果没有阴影则返回null
     */
    public Color getShadowColor() {
        return shadowColor;
    }
    
    /**
     * 判断是否有阴影效果
     * 
     * @return 是否有阴影效果
     */
    public boolean hasShadow() {
        return shadowColor != null && (shadowBlur > 0 || shadowOffsetX != 0 || shadowOffsetY != 0);
    }
    
    /**
     * 创建一个新的TextStyle，使用新的字体族
     * 
     * @param fontFamily 新的字体族
     * @return 新的TextStyle对象
     */
    public TextStyle withFontFamily(String fontFamily) {
        return new TextStyle(fontFamily, this.fontSize, this.lineHeight, this.color, this.bold, this.italic,
                            this.horizontalAlign, this.verticalAlign, this.decoration, this.rotation,
                            this.shadowOffsetX, this.shadowOffsetY, this.shadowBlur, this.shadowColor);
    }
    
    /**
     * 创建一个新的TextStyle，使用新的字体大小
     * 
     * @param fontSize 新的字体大小
     * @return 新的TextStyle对象
     */
    public TextStyle withFontSize(double fontSize) {
        return new TextStyle(this.fontFamily, fontSize, this.lineHeight, this.color, this.bold, this.italic,
                            this.horizontalAlign, this.verticalAlign, this.decoration, this.rotation,
                            this.shadowOffsetX, this.shadowOffsetY, this.shadowBlur, this.shadowColor);
    }
    
    /**
     * 创建一个新的TextStyle，使用新的行高
     * 
     * @param lineHeight 新的行高
     * @return 新的TextStyle对象
     */
    public TextStyle withLineHeight(double lineHeight) {
        return new TextStyle(this.fontFamily, this.fontSize, lineHeight, this.color, this.bold, this.italic,
                            this.horizontalAlign, this.verticalAlign, this.decoration, this.rotation,
                            this.shadowOffsetX, this.shadowOffsetY, this.shadowBlur, this.shadowColor);
    }
    
    /**
     * 创建一个新的TextStyle，使用新的颜色
     * 
     * @param color 新的颜色
     * @return 新的TextStyle对象
     */
    public TextStyle withColor(Color color) {
        return new TextStyle(this.fontFamily, this.fontSize, this.lineHeight, color, this.bold, this.italic,
                            this.horizontalAlign, this.verticalAlign, this.decoration, this.rotation,
                            this.shadowOffsetX, this.shadowOffsetY, this.shadowBlur, this.shadowColor);
    }
    
    /**
     * 创建一个新的TextStyle，设置粗体
     * 
     * @param bold 是否粗体
     * @return 新的TextStyle对象
     */
    public TextStyle withBold(boolean bold) {
        return new TextStyle(this.fontFamily, this.fontSize, this.lineHeight, this.color, bold, this.italic,
                            this.horizontalAlign, this.verticalAlign, this.decoration, this.rotation,
                            this.shadowOffsetX, this.shadowOffsetY, this.shadowBlur, this.shadowColor);
    }
    
    /**
     * 创建一个新的TextStyle，设置斜体
     * 
     * @param italic 是否斜体
     * @return 新的TextStyle对象
     */
    public TextStyle withItalic(boolean italic) {
        return new TextStyle(this.fontFamily, this.fontSize, this.lineHeight, this.color, this.bold, italic,
                            this.horizontalAlign, this.verticalAlign, this.decoration, this.rotation,
                            this.shadowOffsetX, this.shadowOffsetY, this.shadowBlur, this.shadowColor);
    }
    
    /**
     * 创建一个新的TextStyle，使用新的水平对齐方式
     * 
     * @param horizontalAlign 新的水平对齐方式
     * @return 新的TextStyle对象
     */
    public TextStyle withHorizontalAlign(HorizontalAlign horizontalAlign) {
        return new TextStyle(this.fontFamily, this.fontSize, this.lineHeight, this.color, this.bold, this.italic,
                            horizontalAlign, this.verticalAlign, this.decoration, this.rotation,
                            this.shadowOffsetX, this.shadowOffsetY, this.shadowBlur, this.shadowColor);
    }
    
    /**
     * 创建一个新的TextStyle，使用新的垂直对齐方式
     * 
     * @param verticalAlign 新的垂直对齐方式
     * @return 新的TextStyle对象
     */
    public TextStyle withVerticalAlign(VerticalAlign verticalAlign) {
        return new TextStyle(this.fontFamily, this.fontSize, this.lineHeight, this.color, this.bold, this.italic,
                            this.horizontalAlign, verticalAlign, this.decoration, this.rotation,
                            this.shadowOffsetX, this.shadowOffsetY, this.shadowBlur, this.shadowColor);
    }
    
    /**
     * 创建一个新的TextStyle，使用新的文本装饰
     * 
     * @param decoration 新的文本装饰
     * @return 新的TextStyle对象
     */
    public TextStyle withDecoration(TextDecoration decoration) {
        return new TextStyle(this.fontFamily, this.fontSize, this.lineHeight, this.color, this.bold, this.italic,
                            this.horizontalAlign, this.verticalAlign, decoration, this.rotation,
                            this.shadowOffsetX, this.shadowOffsetY, this.shadowBlur, this.shadowColor);
    }
    
    /**
     * 创建一个新的TextStyle，使用新的旋转角度
     * 
     * @param rotation 新的旋转角度（弧度）
     * @return 新的TextStyle对象
     */
    public TextStyle withRotation(double rotation) {
        return new TextStyle(this.fontFamily, this.fontSize, this.lineHeight, this.color, this.bold, this.italic,
                            this.horizontalAlign, this.verticalAlign, this.decoration, rotation,
                            this.shadowOffsetX, this.shadowOffsetY, this.shadowBlur, this.shadowColor);
    }
    
    /**
     * 创建一个新的TextStyle，使用新的阴影设置
     * 
     * @param offsetX 阴影X偏移
     * @param offsetY 阴影Y偏移
     * @param blur 阴影模糊半径
     * @param color 阴影颜色
     * @return 新的TextStyle对象
     */
    public TextStyle withShadow(double offsetX, double offsetY, double blur, Color color) {
        return new TextStyle(this.fontFamily, this.fontSize, this.lineHeight, this.color, this.bold, this.italic,
                            this.horizontalAlign, this.verticalAlign, this.decoration, this.rotation,
                            offsetX, offsetY, blur, color);
    }
    
    /**
     * 创建一个新的TextStyle，移除阴影效果
     * 
     * @return 新的TextStyle对象
     */
    public TextStyle withoutShadow() {
        return new TextStyle(this.fontFamily, this.fontSize, this.lineHeight, this.color, this.bold, this.italic,
                            this.horizontalAlign, this.verticalAlign, this.decoration, this.rotation,
                            0, 0, 0, null);
    }
    
    /**
     * 获取字体权重字符串
     * 
     * @return 字体权重字符串，粗体返回"bold"，否则返回"normal"
     */
    public String getFontWeightString() {
        return bold ? "bold" : "normal";
    }
    
    /**
     * 获取字体样式字符串
     * 
     * @return 字体样式字符串，斜体返回"italic"，否则返回"normal"
     */
    public String getFontStyleString() {
        return italic ? "italic" : "normal";
    }
    
    /**
     * 获取水平对齐方式字符串
     * 
     * @return 水平对齐方式字符串
     */
    public String getHorizontalAlignString() {
        switch (horizontalAlign) {
            case LEFT:
                return "left";
            case CENTER:
                return "center";
            case RIGHT:
                return "right";
            default:
                return "left";
        }
    }
    
    /**
     * 获取垂直对齐方式字符串
     * 
     * @return 垂直对齐方式字符串
     */
    public String getVerticalAlignString() {
        switch (verticalAlign) {
            case TOP:
                return "top";
            case MIDDLE:
                return "middle";
            case BOTTOM:
                return "bottom";
            case BASELINE:
                return "baseline";
            default:
                return "baseline";
        }
    }
    
    /**
     * 获取文本装饰字符串
     * 
     * @return 文本装饰字符串
     */
    public String getDecorationString() {
        switch (decoration) {
            case UNDERLINE:
                return "underline";
            case OVERLINE:
                return "overline";
            case LINE_THROUGH:
                return "line-through";
            case NONE:
            default:
                return "none";
        }
    }
    
    /**
     * 获取完整的字体字符串，包含大小、字体族、粗体和斜体
     * 
     * @return 完整的字体字符串
     */
    public String getFontString() {
        StringBuilder font = new StringBuilder();
        if (italic) {
            font.append("italic ");
        }
        if (bold) {
            font.append("bold ");
        }
        font.append(fontSize).append("px ");
        font.append(fontFamily);
        
        return font.toString();
    }
    
    /**
     * 获取CSS样式字符串表示
     * 
     * @return CSS样式字符串
     */
    public String toCssString() {
        StringBuilder css = new StringBuilder();
        
        // 字体相关
        css.append("font-family: ").append(fontFamily).append(";");
        css.append("font-size: ").append(fontSize).append("px;");
        css.append("line-height: ").append(lineHeight).append(";");
        css.append("color: ").append(color.toCssString()).append(";");
        css.append("font-weight: ").append(getFontWeightString()).append(";");
        css.append("font-style: ").append(getFontStyleString()).append(";");
        
        // 对齐方式
        css.append("text-align: ").append(getHorizontalAlignString()).append(";");
        css.append("vertical-align: ").append(getVerticalAlignString()).append(";");
        
        // 装饰
        css.append("text-decoration: ").append(getDecorationString()).append(";");
        
        // 旋转
        if (rotation != 0) {
            css.append("transform: rotate(").append(Math.toDegrees(rotation)).append("deg);");
        }
        
        // 阴影
        if (hasShadow()) {
            css.append("text-shadow: ")
               .append(shadowOffsetX).append("px ")
               .append(shadowOffsetY).append("px ")
               .append(shadowBlur).append("px ")
               .append(shadowColor.toCssString())
               .append(";");
        }
        
        return css.toString();
    }
    
    /**
     * 获取SVG文本属性表示
     * 
     * @return SVG属性字符串
     */
    public String toSvgAttributes() {
        StringBuilder attrs = new StringBuilder();
        
        // 字体相关
        attrs.append("font-family=\"").append(fontFamily).append("\" ");
        attrs.append("font-size=\"").append(fontSize).append("\" ");
        attrs.append("fill=\"").append(color.toHexString(true)).append("\" ");
        attrs.append("font-weight=\"").append(getFontWeightString()).append("\" ");
        attrs.append("font-style=\"").append(getFontStyleString()).append("\" ");
        
        // 对齐方式
        attrs.append("text-anchor=\"");
        switch (horizontalAlign) {
            case LEFT:
                attrs.append("start");
                break;
            case CENTER:
                attrs.append("middle");
                break;
            case RIGHT:
                attrs.append("end");
                break;
            default:
                attrs.append("start");
        }
        attrs.append("\" ");
        
        attrs.append("dominant-baseline=\"");
        switch (verticalAlign) {
            case TOP:
                attrs.append("text-before-edge");
                break;
            case MIDDLE:
                attrs.append("central");
                break;
            case BOTTOM:
                attrs.append("text-after-edge");
                break;
            case BASELINE:
                attrs.append("alphabetic");
                break;
            default:
                attrs.append("alphabetic");
        }
        attrs.append("\" ");
        
        // 装饰
        if (decoration != TextDecoration.NONE) {
            attrs.append("text-decoration=\"").append(getDecorationString()).append("\" ");
        }
        
        // 旋转
        if (rotation != 0) {
            attrs.append("transform=\"rotate(")
                .append(Math.toDegrees(rotation))
                .append(")\" ");
        }
        
        // 阴影需要单独使用filter来实现
        
        return attrs.toString().trim();
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        
        TextStyle textStyle = (TextStyle) o;
        
        if (Double.compare(textStyle.fontSize, fontSize) != 0) return false;
        if (Double.compare(textStyle.lineHeight, lineHeight) != 0) return false;
        if (bold != textStyle.bold) return false;
        if (italic != textStyle.italic) return false;
        if (Double.compare(textStyle.rotation, rotation) != 0) return false;
        if (Double.compare(textStyle.shadowOffsetX, shadowOffsetX) != 0) return false;
        if (Double.compare(textStyle.shadowOffsetY, shadowOffsetY) != 0) return false;
        if (Double.compare(textStyle.shadowBlur, shadowBlur) != 0) return false;
        if (!Objects.equals(fontFamily, textStyle.fontFamily)) return false;
        if (!Objects.equals(color, textStyle.color)) return false;
        if (horizontalAlign != textStyle.horizontalAlign) return false;
        if (verticalAlign != textStyle.verticalAlign) return false;
        if (decoration != textStyle.decoration) return false;
        return Objects.equals(shadowColor, textStyle.shadowColor);
    }
    
    @Override
    public int hashCode() {
        int result;
        long temp;
        result = fontFamily != null ? fontFamily.hashCode() : 0;
        temp = Double.doubleToLongBits(fontSize);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(lineHeight);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        result = 31 * result + (color != null ? color.hashCode() : 0);
        result = 31 * result + (bold ? 1 : 0);
        result = 31 * result + (italic ? 1 : 0);
        result = 31 * result + (horizontalAlign != null ? horizontalAlign.hashCode() : 0);
        result = 31 * result + (verticalAlign != null ? verticalAlign.hashCode() : 0);
        result = 31 * result + (decoration != null ? decoration.hashCode() : 0);
        temp = Double.doubleToLongBits(rotation);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(shadowOffsetX);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(shadowOffsetY);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        temp = Double.doubleToLongBits(shadowBlur);
        result = 31 * result + (int) (temp ^ (temp >>> 32));
        result = 31 * result + (shadowColor != null ? shadowColor.hashCode() : 0);
        return result;
    }
    
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("TextStyle{");
        sb.append("font='").append(getFontString()).append('\'');
        sb.append(", color=").append(color);
        
        if (horizontalAlign != DEFAULT_HORIZONTAL_ALIGN) {
            sb.append(", horizontalAlign=").append(horizontalAlign);
        }
        
        if (verticalAlign != DEFAULT_VERTICAL_ALIGN) {
            sb.append(", verticalAlign=").append(verticalAlign);
        }
        
        if (decoration != TextDecoration.NONE) {
            sb.append(", decoration=").append(decoration);
        }
        
        if (rotation != 0) {
            sb.append(", rotation=").append(rotation);
        }
        
        if (hasShadow()) {
            sb.append(", shadow=[").append(shadowOffsetX).append(',')
              .append(shadowOffsetY).append(',').append(shadowBlur).append(',')
              .append(shadowColor).append(']');
        }
        
        sb.append('}');
        return sb.toString();
    }
} 